<script setup lang="ts" name="Father">//setup语法糖
import { ref, reactive, toRefs, toRef, computed, watch, watchEffect, defineExpose, defineProps, withDefaults, onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted, provide } from 'vue'
import Child from './Child.vue'
import Brother from './Brother.vue'
let name = ref('zhangsan') //ref响应式(RefImpl对象): 基本类型(数字,字符串), 对象(层级不深)
let cars = ref({ brand: '奔驰', price: 100 }) //ref对象(层级不深)
let car = reactive({ brand: '奔驰', price: 100 }) //reactive相应式(Proxy代理函数): 只能对象数组(层级深)
let { brand, price } = toRefs(car) //toRefs: 将reactive中k-v全转为ref,解构赋值为响应式(ObjectRefImpl)
let brands = toRef(car, 'brand') //toRef: 将reactive中某个k-v转为ref
let computedResult = computed({ //计算属性(ref响应式)
  get() {
  },
  set(val) {
  }
})
const stopWatch = watch(name, (newValue, oldValue) => { //监视ref基本类型,不写.value

})
watchEffect(() => { //自动监视:不用指定监视谁,用到就监视,立即监视(一上来就监视)

})
function generalMethod() { //一般方法

}

import { useRoute } from 'vue-router' //路由query传参
let route = useRoute() //路由query传参

let toy = ref('')
function getToy(value: string) { //子传父(父先给子函数)
  toy.value = value //父接收子
}

function saveToy(value: string) { //子传父(自定义事件)
  toy.value = value
}

function updateA(value: string) { //$attrs孙传爷(爷先给孙函数)
  toy.value = value
}

let c1 = ref() //ref只能获取1个子
function changeToy() {
  c1.value.toy = '佩奇'
}

function getAllChild(refs: { [key: string]: any }) { //$refs获取全部子
  for (let key in refs) {
    refs[key].book += 3
  }
}

let house = ref(5)
defineExpose({ house }) //宏函数(将父受保护数据交出去)

let money = ref(100)
provide('moneys', { money, updateMoney }) //爷传孙(不打扰子)
provide('car', car)
function updateMoney(value: number) { //provide孙传爷(准备函数)
  money.value -= value
}
</script>

<template> <!--template不编译-->
  <div class="component-name"> <!--vue3无需根标签-->
    父组件
  </div>
  <div class="component-name">
    <h1>路由query接收参数:{{ route.query.id }}</h1>
    <RouterView></RouterView> <!--路由视图-->
  </div>

  <Child :car="car" :sendToy="getToy" /><br /> <!--props父传子(直接传),子传父(父先给子函数)-->
  父接收子:{{ toy }} <br />

  <Child @self-event="saveToy" /><br /> <!--子传父(自定义事件)-->
  父接收子(自定义事件):{{ toy }}
  <hr />

  <Brother />
  <!--组件标签上v-model原理:动态modelValue+update:modelValue事件-->
  <!-- <Brother :modelValue="name" @update:modelValue="name = $event" /> -->
  <!-- {{ name }} -->
  <Brother v-model:ming="name" v-model:mima="name" /><br /> <!--组件标签v-model:改名-->
  {{ name }}

  <Child :car="car" v-bind="{ toy: car }" :updateA="updateA" /><br /> <!--$attrs爷传孙-->
  $attrs接收子传爷:{{ toy }}
  <hr />

  <Child ref="c1" /><br /> <!--ref只能获取1个子-->
  <button @click="changeToy">ref只能获取1个子</button> <br />
  <button @click="getAllChild($refs)">$refs父传子数据</button> <!--$refs获取全部子-->

  $parant子传父:{{ house }}
  <hr />

  <Child title="热门游戏列表">
    <span>你好{{ name }}</span> <!--默认插槽(组件标签内的标签,会被塞到插槽slot)-->
  </Child>
  <Child title="热门游戏列表">
    <template v-slot:slotName> <!--名称只能放在组件标签或template标签上-->
      <span>你好{{ name }}</span> <!--具名插槽-->
    </template>
    <template #slotNames>
      <span>你好{{ name }}</span> <!--具名插槽(简写)-->
    </template>
  </Child>
  <Child title="热门游戏列表">
    <template v-slot="params"> <!--父接收子-->
      <span>你好{{ params.games }}</span> <!--作用域插槽:子传父,games子数据,结构由父决定-->
    </template>
  </Child>
</template>

<style lang="less" scoped>
//less嵌套写法,scoped域:样式只对当前组件有效
.component-name {}
</style>